﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using VIBlend.WPF.Controls;

namespace AnonsaiWPF.CSharp.DataGridViewDemos
{
    [Category("VIBlend.WPF.Examples")]
    public partial class MultiLevelHierarchies: Window, IWindow
    {
        #region IWindow Members

        public void DetachContent()
        {
            RemoveLogicalChild(Content);
        }

        public Grid Root
        {
            get
            {
                return this.LayoutRoot;
            }
        }
        #endregion
        HierarchyItem germany;
        HierarchyItem spain;
        HierarchyItem france;
        TextBox textBox;
        private Key pressedKey;

        DataTemplate cellEditTextBoxTemplate;

        public void SetTheme()
        {
            dataGrid1.FontFamily = new FontFamily("Tahoma");
        }
  
        public MultiLevelHierarchies()
        {   
            InitializeComponent();
            this.CreateHierarchies();
        }

        // Creates a custom hierarchy programatically in unbound mode.
        private void CreateHierarchies()
        {     
            VIBlend.WPF.Controls.DataGrid dataGridView = this.dataGrid1;
            dataGrid1.IsManualEditUpdateModeEnabled = true;
            for (int i = 0; i < 15; i++)
            {
                HierarchyItem rowItemTopLevel = dataGridView.RowsHierarchy.Items.Add(i.ToString());
            }

            HierarchyItem dateItem = dataGridView.ColumnsHierarchy.Items.Add("DATE");
            HierarchyItem sales = dataGridView.ColumnsHierarchy.Items.Add("SALES");
            dateItem.CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
            sales.CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
            dateItem.CellTextFormatString = "{0:d}";

            germany = sales.Items.Add("GERMANY");
            germany.Items.Add("PREV YEAR");
            germany.Items.Add("THIS YEAR");
            germany.Expanded = true;
            germany.ExpandCollapseEnabled = false;

            spain = sales.Items.Add("SPAIN");
            spain.Expanded = true;
            spain.Items.Add("PREV YEAR");
            spain.Items.Add("THIS YEAR");
            spain.Expanded = true;
            spain.ExpandCollapseEnabled = false;

            france = sales.Items.Add("FRANCE");
            france.Items.Add("PREV YEAR");
            france.Items.Add("THIS YEAR");
            france.Expanded = true;
            france.ExpandCollapseEnabled = false;
            dataGridView.ColumnsHierarchy.ExpandAllItems();
            sales.ExpandCollapseEnabled = false;

            france.CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
            spain.CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
            germany.CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;

            // Fills dates column.
            this.FillData(dataGridView, dateItem);

            this.cellEditTextBoxTemplate = this.Resources["cellEditTextBoxTemplate"] as DataTemplate;
            EditorActivationFlags activationFlags = EditorActivationFlags.KEY_PRESS | EditorActivationFlags.MOUSE_DBLCLICK | EditorActivationFlags.MOUSE_CLICK_SELECTED_CELL;
         
            germany.Items[1].CellEditTemplate = this.cellEditTextBoxTemplate;
            germany.Items[1].CellEditorActivationFlags = activationFlags;
            germany.Items[1].CellEditorDeActivationFlags = EditorActivationFlags.MOUSE_CLICK;

            france.Items[1].CellEditTemplate = this.cellEditTextBoxTemplate;
            france.Items[1].CellEditorActivationFlags = activationFlags;
            france.Items[1].CellEditorDeActivationFlags = EditorActivationFlags.MOUSE_CLICK;
            
            spain.Items[1].CellEditTemplate = this.cellEditTextBoxTemplate;
            spain.Items[1].CellEditorActivationFlags = activationFlags;
            spain.Items[1].CellEditorDeActivationFlags = EditorActivationFlags.MOUSE_CLICK;
            SummaryValue();
            
            // Autoresize the row items to best fit
            dataGridView.RowsHierarchy.AutoResize(AutoResizeMode.FIT_CELL_CONTENT);
            dataGridView.ColumnsHierarchy.AutoResize(AutoResizeMode.FIT_CELL_CONTENT);
         
            // Manually adjust header sizes.
            this.dataGrid1.ColumnsHierarchy.Items[0].Width = 100;
            this.dataGrid1.ColumnsHierarchy.Items[1].Width = 460;
            germany.Width = 150;
            spain.Width = 150;
            france.Width = 150;

            germany.Items[0].Width = 75;
            germany.Items[1].Width = 80;
            germany.Items[0].CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
            germany.Items[1].CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
           
            spain.Items[0].Width = 75;
            spain.Items[1].Width = 80;
            spain.Items[0].CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
            spain.Items[1].CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
       
            france.Items[0].Width = 75;
            france.Items[1].Width = 75;
            france.Items[0].CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
            france.Items[1].CellStyle = Application.Current.Resources["TextCenteredCellStyle"] as Style;
       
            // This event occurs when the editor is de activated, after the edit operation is finished.
            dataGrid1.CellEditorDeActivated += new VIBlend.WPF.Controls.DataGrid.CellEventHandler(dataGrid1_CellEditorDeActivated);
         
            // This event occurs when the user input is validated, before saving the value.
            dataGrid1.CellValidating += new VIBlend.WPF.Controls.DataGrid.CellCancelEventHandler(dataGrid1_CellValidating);
        
            // This event occurs when the editor is activated.
            dataGrid1.CellEditorActivated += new VIBlend.WPF.Controls.DataGrid.CellEventHandler(dataGrid1_CellEditorActivated);
        
            // This event occurs when the user presses a key.
            dataGrid1.PreviewKeyDown += new KeyEventHandler(dataGrid1_PreviewKeyDown);

            this.dataGrid1.Refresh();
        }

        void dataGrid1_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            pressedKey = e.Key;
        }
 
        void dataGrid1_CellEditorActivated(object sender, CellEventArgs args)
        {
            // Deletes the selected cell value and closes te editor, when the Esc key is pressed.
            if (pressedKey == Key.Delete)
            {
                this.dataGrid1.CloseEditor(true);
                this.dataGrid1.CellsArea.SetCellValue(args.Cell.RowItem, args.Cell.ColumnItem, "");
                this.SummaryValue();
                this.dataGrid1.Refresh();
                return;
            }

            this.textBox = args.Cell.EditorElement as TextBox;
            if (this.textBox != null)
            {
               // Subscribe to the TextBox control's KeyDown and TextChanged events.
               this.textBox.KeyDown += new KeyEventHandler(textBox_KeyDown);
               this.textBox.TextChanged += new TextChangedEventHandler(textBox_TextChanged);

               // Sets the value to the textbox, which uses the pressed Key. 
               SetInitialValue(args.Cell);               
            }
        }

        private void SetInitialValue(GridCell cell)
        {
            object value = this.dataGrid1.CellsArea.GetCellValue(cell.RowItem, cell.ColumnItem);
           
            int number = 0;
            switch (pressedKey)
            {
                case Key.D1:
                case Key.NumPad1:
                    number = 1;
                    break;
                case Key.D2:
                case Key.NumPad2:
                    number = 2;
                    break;
                case Key.D3:
                case Key.NumPad3:
                    number = 3;
                    break;
                case Key.NumPad4:
                case Key.D4:
                    number = 4;
                    break;
                case Key.NumPad5:
                case Key.D5:
                    number = 5;
                    break;
                case Key.NumPad6:
                case Key.D6:
                    number = 6;
                    break;
                case Key.NumPad7:
                case Key.D7:
                    number = 7;
                    break;
                case Key.NumPad8:
                case Key.D8:
                    number = 8;
                    break;
                case Key.NumPad9:
                case Key.D9:
                    number = 9;
                    break;
            }

            if (number > 0)
            {
                this.textBox.Text = this.textBox.Text + number;
                this.textBox.SelectionStart = this.textBox.Text.Length;
            }
        }

        void textBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (e.UndoAction == UndoAction.Create && String.IsNullOrEmpty(this.textBox.Text))
            {
                SetInitialValue(this.dataGrid1.CellsArea.EditCell);         
            }
        }

        void dataGrid1_CellValidating(object sender, CellCancelEventArgs args)
        {
            // If the TextBox's value has characters which are not digits, cancel the validation operation.
            // This ensures that the grid stays in edit mode.

            this.textBox = this.dataGrid1.CellsArea.EditCell.EditorElement as TextBox;

            for (int i = 0; i < this.textBox.Text.Length; i++)
            {
                char ch = this.textBox.Text[i];
                if (!Char.IsDigit(ch))
                {
                    args.Cancel = true;
                    return;
                }
            }
        }     

        private void FillData(VIBlend.WPF.Controls.DataGrid dataGridView, HierarchyItem dateItem)
        {
            DateTime date = new DateTime(2010, 1, 1);
            for (int i = 0; i < 14; i++)
            {
                dataGridView.CellsArea.SetCellValue(dataGridView.RowsHierarchy.Items[i], dateItem, date);
                date = date.AddDays(1);
            }

            // Set PREV YEAR VALUES

            string[] prevYear = { "3000", "3530", "293", "3223", "234", "213", "2351", "123", "123", "123", "4214", "123", "41", "23", "12", "3", "21" };
            for (int i = 0; i < 14; i++)
            {
                dataGridView.CellsArea.SetCellValue(dataGridView.RowsHierarchy.Items[i], germany.Items[0], prevYear[i]);
                dataGridView.CellsArea.SetCellValue(dataGridView.RowsHierarchy.Items[i], spain.Items[0], prevYear[i]);
                dataGridView.CellsArea.SetCellValue(dataGridView.RowsHierarchy.Items[i], france.Items[0], prevYear[i]);
            }

            germany.Items[1].CellDataSource = GridCellDataSource.Virtual;
            spain.Items[1].CellDataSource = GridCellDataSource.Virtual;
            france.Items[1].CellDataSource = GridCellDataSource.Virtual;

            double[] thisYearValues = { 3200, 3100, 500, 3500 };
            for (int i = 0; i < 4; i++)
            {
                dataGridView.CellsArea.SetCellValue(dataGridView.RowsHierarchy.Items[i], germany.Items[1], thisYearValues[i]);
            }
        }

        void textBox_KeyDown(object sender, KeyEventArgs e)
        {
            // Closes the editor if the user presses Escape, Enter or Tab keys.

            if (e.Key == Key.Enter || e.Key == Key.Tab)
            {
                this.dataGrid1.CloseEditor(false);
                e.Handled = true;
            }
            else if (e.Key == Key.Escape)
            {
                this.dataGrid1.CloseEditor(true);
                e.Handled = true;
            }
        }

        void dataGrid1_CellEditorDeActivated(object sender, CellEventArgs args)
        {
            this.textBox = this.dataGrid1.CellsArea.EditCell.EditorElement as TextBox;

            dataGrid1.CellsArea.SetCellValue(args.Cell.RowItem, args.Cell.ColumnItem, this.textBox.Text);

            SummaryValue();
            this.pressedKey = Key.D0;
        }

        // calculates the totals.
        private void SummaryValue()
        {
            for (int j = 0; j < 3; j++)
            {
                double sum = 0;
                for (int i = 0; i < 14; i++)
                {
                    HierarchyItem item = this.dataGrid1.ColumnsHierarchy.Items[1].Items[j].Items[1];

                    string s = "" + this.dataGrid1.CellsArea.GetCellValue(this.dataGrid1.RowsHierarchy.Items[i], item);

                    if (this.dataGrid1.CellsArea.EditCell != null && this.dataGrid1.CellsArea.EditCell.RowItem == this.dataGrid1.RowsHierarchy.Items[i] && this.dataGrid1.CellsArea.EditCell.ColumnItem == item)
                    {
                        s = "" + this.dataGrid1.CellsArea.EditCell.Value;
                    }

                    if (!String.IsNullOrEmpty(s))
                    {
                        double value;

                        if (double.TryParse(s, out value))
                        {
                            sum += value;
                        }
                    }
                }

                this.dataGrid1.CellsArea.SetCellValue(this.dataGrid1.RowsHierarchy.Items[this.dataGrid1.RowsHierarchy.Items.Count - 1], this.dataGrid1.ColumnsHierarchy.Items[1].Items[j].Items[1], "SUM:" + sum);
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
          
            this.dataGrid1.CellEditorDeActivated -= new VIBlend.WPF.Controls.DataGrid.CellEventHandler(dataGrid1_CellEditorDeActivated);
            this.dataGrid1.CellValidating -= new VIBlend.WPF.Controls.DataGrid.CellCancelEventHandler(dataGrid1_CellValidating);
            this.dataGrid1.CellEditorActivated -= new VIBlend.WPF.Controls.DataGrid.CellEventHandler(dataGrid1_CellEditorActivated);
            this.dataGrid1.PreviewKeyDown -= new KeyEventHandler(dataGrid1_PreviewKeyDown);
        
            this.dataGrid1.Dispose();
            this.dataGrid1 = null;
        }
    }

 }
